﻿using SketchUpAPI.NET.Enums;
using SketchUpAPI.NET.SketchUp.Exception;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.Remoting.Messaging;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;

namespace SketchUpAPI.NET.Objects
{
    /// <summary>
    /// 引注文字
    /// </summary>
    /// <remarks>对 SketchUpAPI 中的 SUTextRef 的包装</remarks>
    public class Text : DrawingElement
    {
        #region API 函数
        /// <summary>
        /// 创建文字
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUTextCreate(out IntPtr text);

        /// <summary>
        /// 释放资源
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUTextRelease(ref IntPtr text);

        /// <summary>
        /// 设置文字内容
        /// </summary>
        /// <param name="text"></param>
        /// <param name="textString"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUTextSetString(IntPtr text, [MarshalAs(UnmanagedType.LPUTF8Str)] string textString);

        /// <summary>
        /// 获取文字内容
        /// </summary>
        /// <param name="text"></param>
        /// <param name="textString"><see cref="StringRef"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUTextGetString(IntPtr text, ref IntPtr textString);

        /// <summary>
        /// 设置字体
        /// </summary>
        /// <param name="text"></param>
        /// <param name="font"><see cref="Font"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUTextSetFont(IntPtr text, IntPtr font);

        /// <summary>
        /// 获取字体
        /// </summary>
        /// <param name="text"></param>
        /// <param name="font"><see cref="Font"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUTextGetFont(IntPtr text, out IntPtr font);

        /// <summary>
        /// 设置引线类型
        /// </summary>
        /// <param name="text"></param>
        /// <param name="leader"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUTextSetLeaderType(IntPtr text, TextLeaderType leader);

        /// <summary>
        /// 获取引线类型
        /// </summary>
        /// <param name="text"></param>
        /// <param name="leader"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUTextGetLeaderType(IntPtr text, out TextLeaderType leader);

        /// <summary>
        /// 设置箭头类型
        /// </summary>
        /// <param name="text"></param>
        /// <param name="arrow_type"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUTextSetArrowType(IntPtr text, ArrowType arrow_type);

        /// <summary>
        /// 获取箭头类型
        /// </summary>
        /// <param name="text"></param>
        /// <param name="arrow_type"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUTextGetArrowType(IntPtr text, out ArrowType arrow_type);

        /// <summary>
        /// 设置关联点
        /// </summary>
        /// <remarks>也可以只使用 <paramref name="point"/> 参数，或者只使用 <paramref name="path"/> 参数，详细用法参考：<a href="https://extensions.sketchup.com/developers/sketchup_c_api/sketchup/struct_s_u_text_ref.html#aeb3f23def0416d36216da5e368132d4b">示例</a></remarks>
        /// <param name="text"></param>
        /// <param name="point"></param>
        /// <param name="path"><see cref="InstancePath"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUTextSetPoint(IntPtr text, Point3D? point, IntPtr path);

        /// <summary>
        /// 获取关联点
        /// </summary>
        /// <param name="text"></param>
        /// <param name="point"></param>
        /// <param name="path"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUTextGetPoint(IntPtr text, ref Point3D point, out IntPtr path);

        /// <summary>
        /// 设置引线方向
        /// </summary>
        /// <param name="text"></param>
        /// <param name="vector"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUTextSetLeaderVector(IntPtr text, Vector3D vector);

        /// <summary>
        /// 获取引线方向
        /// </summary>
        /// <param name="text"></param>
        /// <param name="vector"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUTextGetLeaderVector(IntPtr text, ref Vector3D vector);

        /// <summary>
        /// 设置颜色
        /// </summary>
        /// <param name="text"></param>
        /// <param name="color"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUTextSetColor(IntPtr text, Color color);

        /// <summary>
        /// 获取颜色
        /// </summary>
        /// <param name="text"></param>
        /// <param name="color"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUTextGetColor(IntPtr text, ref Color color);

        /// <summary>
        /// 设置屏幕位置
        /// </summary>
        /// <param name="text"></param>
        /// <param name="percent_x">百分比位置 0~1</param>
        /// <param name="percent_y">百分比位置 0~1</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUTextSetScreenPosition(IntPtr text, double percent_x, double percent_y);

        /// <summary>
        /// 获取屏幕位置
        /// </summary>
        /// <param name="text"></param>
        /// <param name="percent_x">百分比位置 0~1</param>
        /// <param name="percent_y">百分比位置 0~1</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUTextGetScreenPosition(IntPtr text, out double percent_x, out double percent_y);
        #endregion

        /// <summary>
        /// 文字内容
        /// </summary>
        public string Content
        {
            get
            {
                StringRef s = StringRef.Empty;
                SketchUpExceptionHelper.ThrowSUResult(SUTextGetString(Id, ref s.Id));
                return s.Dispose();
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUTextSetString(Id, value));
            }
        }

        /// <summary>
        /// 文字字体
        /// </summary>
        public Font TextFont
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUTextGetFont(Id, out IntPtr id));
                return new Font(id);
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUTextSetFont(Id, value.Id));
            }
        }

        /// <summary>
        /// 引线类型
        /// </summary>
        public TextLeaderType LeaderType
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUTextGetLeaderType(Id, out TextLeaderType leader));
                return leader;
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUTextSetLeaderType(Id, value));
            }
        }

        /// <summary>
        /// 引线方向
        /// </summary>
        public Vector3D LeaderVector
        {
            get
            {
                Vector3D v = new Vector3D();
                SketchUpExceptionHelper.ThrowSUResult(SUTextGetLeaderVector(Id, ref v));
                return v;
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUTextSetLeaderVector(Id, value));
            }
        }

        /// <summary>
        /// 箭头类型
        /// </summary>
        public ArrowType ArrowType
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUTextGetArrowType(Id, out ArrowType arrowType));
                return arrowType;
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUTextSetArrowType(Id, value));
            }
        }

        /// <summary>
        /// 文字颜色
        /// </summary>
        public Color Color
        {
            get
            {
                Color c = new Color();
                SketchUpExceptionHelper.ThrowSUResult(SUTextGetColor(Id, ref c));
                return c;
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUTextSetColor(Id, value));
            }
        }

        internal Text(IntPtr id) : base(id) { }

        /// <summary>
        /// 创建文字
        /// </summary>
        public Text()
        {
            SketchUpExceptionHelper.ThrowSUResult(SUTextCreate(out Id));
        }

        /// <summary>
        /// 设置引用点
        /// </summary>
        /// <remarks>也可以只使用 <paramref name="point"/> 参数，或者只使用 <paramref name="path"/> 参数，详细用法参考：<a href="https://extensions.sketchup.com/developers/sketchup_c_api/sketchup/struct_s_u_text_ref.html#aeb3f23def0416d36216da5e368132d4b">示例</a></remarks>
        /// <param name="point"></param>
        /// <param name="path"></param>
        public void SetPoint(Point3D? point, InstancePath path)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUTextSetPoint(Id, point, path?.Id ?? IntPtr.Zero));
        }

        /// <summary>
        /// 获取引用点
        /// </summary>
        /// <param name="point"></param>
        /// <param name="path"></param>
        public void GetPoint(out Point3D point, out InstancePath path)
        {
            point = new Point3D();
            path = new InstancePath();
            SketchUpExceptionHelper.ThrowSUResult(SUTextGetPoint(Id, ref point, out path.Id));
            if (path.Id == IntPtr.Zero)
            {
                path.Dispose();
                path = null;
            }
        }

        /// <summary>
        /// 设置文字在在窗口中的位置
        /// </summary>
        /// <remarks>仅在没有引线时使用</remarks>
        /// <param name="x"></param>
        /// <param name="y"></param>
        public void SetScreenPosition(double x, double y)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUTextSetScreenPosition(Id, x, y));
        }

        /// <summary>
        /// 获取文字在在窗口中的位置
        /// </summary>
        /// <remarks>仅在没有引线时使用</remarks>
        /// <param name="x"></param>
        /// <param name="y"></param>
        public void GetScreenPosition(out double x, out double y)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUTextGetScreenPosition(Id, out x, out y));
        }

        public override void Dispose()
        {
            SketchUpExceptionHelper.ThrowSUResult(SUTextRelease(ref Id));
        }
    }
}